package com.asman.worker.rn_ui;

import com.asman.oss.Config;
import com.asman.worker.utils.SizeUtils;
import com.asman.worker.widgets.multiFile.AddImageGridLayout;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * @author ybk
 * @date :2019-10-15 10:44
 * @desc:
 */
public class NativeGridUploadMulti extends SimpleViewManager<AddImageGridLayout> {

    public static final String REACT_CLASS = "NativeGridUploadMulti";

    private ThemedReactContext reactContext;

    @Override
    public @Nonnull
    String getName() {
        return REACT_CLASS;
    }

    @Nonnull
    @Override
    protected AddImageGridLayout createViewInstance(@Nonnull ThemedReactContext reactContext) {
        this.reactContext = reactContext;
        AddImageGridLayout view = new AddImageGridLayout(reactContext.getCurrentActivity() == null ? reactContext : reactContext.getCurrentActivity());
        view.setReactContext(reactContext);
        view.setOnSizeChange((width, height) -> {
            callJSOnSizeChange(reactContext, view, height);
        });
        return view;
    }

    @ReactProp(name = "interceptFirstClick", defaultBoolean = false)
    public void setInterceptFirstClick(AddImageGridLayout view, Boolean intercept) {
        if (intercept) {
            view.setOnFirstAddClickListener(() -> {
                callJSOnFirstClick(reactContext, view);
            });
        } else {
            view.setOnFirstAddClickListener(null);
        }
    }

    @ReactProp(name = "maxCount", defaultDouble = 0)
    public void setMaxCount(AddImageGridLayout view, Integer maxCount) {
        view.setMaxCount(maxCount);
    }

    @ReactProp(name = "lastImageUrls")
    public void setLastImageUrls(AddImageGridLayout view, ReadableArray imageUrls) {
        List<String> list;
        try {
            list = new Gson().fromJson(imageUrls.toString(), new TypeToken<List<String>>() {
            }.getType());
        } catch (JsonSyntaxException e) {
            list = null;
        }
        view.setLastImages(list);
    }

    /**
     * 这是可以选择的 多媒体类型
     *
     * @param view AddImageGridLayout
     * @param type type 1：照片，2：照片+视频
     */
    @ReactProp(name = "multiType", defaultDouble = 0)
    public void setMultiType(AddImageGridLayout view, Integer type) {
        if (type == 1) {
            view.setVideoEnable(false);
        } else if (type == 2) {
            view.setVideoEnable(true);
        }
    }

    @ReactProp(name = "sts", defaultDouble = 0)
    public void setSTS(AddImageGridLayout view, String sts) {
        Config.STS_SERVER_URL = sts;
    }

    @ReactProp(name = "bucketName")
    public void setBucketName(AddImageGridLayout view, String bucketName) {
        view.setBucketName(bucketName);
    }

    @ReactProp(name = "endpoint")
    public void setEndpoint(AddImageGridLayout view, String endpoint) {
        view.setEndpoint(endpoint);
    }

    private int lastHeight = 0;//上一次的控件高度

    private void callJSOnSizeChange(@Nonnull ThemedReactContext reactContext, AddImageGridLayout view, int height) {
        //计算得到当前需要的高度
        int currentHeight = getHeightDP(view);
        if (lastHeight == currentHeight) {
            return;
        }
        // 创建数据传递信使，类似于Android中的Bundle
        WritableMap data = Arguments.createMap();
        data.putDouble("height", currentHeight);
        reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                view.getId(), // RN层原生层根据id绑定在一起
                EVENT_NAME_ON_SIZE_CHANGE, // 事件名称
                data // 传递的数据
        );
        lastHeight = currentHeight;
    }

    private int getHeightDP(AddImageGridLayout view) {
        int count = Math.min(view.getImageCount(), view.getMaxCount());
        return SizeUtils.INSTANCE.px2dp((float) (Math.ceil(count / 3.0) * view.getItemWidth()));
    }

    /**
     * @param reactContext ThemedReactContext
     * @param view         AddImageGridLayout
     */
    private void callJSOnFirstClick(@Nonnull ThemedReactContext reactContext, AddImageGridLayout view) {
        // 创建数据传递信使，类似于Android中的Bundle
        WritableMap data = Arguments.createMap();
        reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                view.getId(), // RN层原生层根据id绑定在一起
                EVENT_NAME_ON_FIRST_CLICK, // 事件名称
                data // 传递的数据
        );
    }

    /**
     * @param reactContext ThemedReactContext
     * @param view         AddImageGridLayout
     */
    private void callJSIsAllSuccess(@Nonnull ThemedReactContext reactContext, AddImageGridLayout view, Boolean isAllSuccess) {
        // 创建数据传递信使，类似于Android中的Bundle
        WritableMap data = Arguments.createMap();
        data.putBoolean("isAllSuccess", isAllSuccess);// key用于在RN中获取传递的数据
        if (isAllSuccess) {
            WritableNativeArray array = new WritableNativeArray();
            if (view.getOSSImageUrls() != null) {
                for (String fileName : view.getOSSImageUrls()) {
                    array.pushString(fileName);
                }
            }
            data.putArray("uploadOSSPaths", array);
        }
        reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                view.getId(), // RN层原生层根据id绑定在一起
                EVENT_NAME_ON_FILE_PATH_CALL_BACK, // 事件名称
                data // 传递的数据
        );
    }

    @Override
    public void updateProperties(@Nonnull AddImageGridLayout viewToUpdate, ReactStylesDiffMap props) {
        super.updateProperties(viewToUpdate, props);
    }

    @Nullable
    @Override
    public Map getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.of(
                EVENT_NAME_ON_FIRST_CLICK, MapBuilder.of("registrationName", EVENT_NAME_ON_FIRST_CLICK),
                EVENT_NAME_ON_FILE_PATH_CALL_BACK, MapBuilder.of("registrationName", EVENT_NAME_ON_FILE_PATH_CALL_BACK),
                EVENT_NAME_ON_SIZE_CHANGE, MapBuilder.of("registrationName", EVENT_NAME_ON_SIZE_CHANGE),
                UPLOAD_COMPLETED, MapBuilder.of("registrationName", UPLOAD_COMPLETED)
        );
    }

    //Native  通知 RN
    public static final String EVENT_NAME_ON_SIZE_CHANGE = "onContentSizeChange";
    public static final String EVENT_NAME_ON_FIRST_CLICK = "onFirstClick";
    public static final String EVENT_NAME_ON_FILE_PATH_CALL_BACK = "onFilePathCallBack";
    public static final String UPLOAD_COMPLETED = "uploadCompleted";

    //接受RN 的消息
    private static final String HANDLE_GET_FILE_PATHS_NAME = "getFilePaths"; // 是否全部上传完
    private static final String HANDLE_SHOW_TAKE_PHOTO_NAME = "showTakePhoto"; // 展示拍照dialog
    private static final String HANDLE_DESTROY_NAME = "destroy"; // 销毁

    private static final int HANDLE_GET_FILE_PATHS = 1; // 是否全部上传完成
    private static final int HANDLE_SHOW_TAKE_PHOTO = 2; // 展示拍照dialog
    private static final int HANDLE_DESTROY = 3; // 销毁

    /**
     * 接收交互通知
     */
    @Nullable
    @Override
    public Map<String, Integer> getCommandsMap() {
        return MapBuilder.of(
                HANDLE_GET_FILE_PATHS_NAME, HANDLE_GET_FILE_PATHS,
                HANDLE_SHOW_TAKE_PHOTO_NAME, HANDLE_SHOW_TAKE_PHOTO,
                HANDLE_DESTROY_NAME, HANDLE_DESTROY
        );
    }

    /**
     * 根据命令ID，处理对应任务
     *
     * @param view
     * @param commandId
     * @param args
     */
    @Override
    public void receiveCommand(@NotNull AddImageGridLayout view, int commandId, @Nullable ReadableArray args) {
        switch (commandId) {
            case HANDLE_GET_FILE_PATHS://是否全部上传完成
                if (args != null) {
                    callJSIsAllSuccess(reactContext, view, view.isAllImageOk());
                }
                break;
            case HANDLE_SHOW_TAKE_PHOTO:
                if (args != null) {
                    view.showPhotoDialog();
                }
                break;
            case HANDLE_DESTROY:
                if (args != null) {
                    view.onDestroy();
                }
                break;
            default:
                break;
        }
    }
}